home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / pmpsrc11.zip / LEVEL1RX.C < prev    next >
Text File  |  1991-07-30  |  5KB  |  198 lines

  1. /*
  2.     level1rx.c -- Level 1 synchronous receive routines
  3.  
  4.   Poor Man's Packet (PMP)
  5.   Copyright (c) 1991 by Andrew C. Payne    All Rights Reserved.
  6.  
  7.   Permission to use, copy, modify, and distribute this software and its
  8.   documentation without fee for NON-COMMERCIAL AMATEUR RADIO USE ONLY is hereby
  9.   granted, provided that the above copyright notice appear in all copies.
  10.   The author makes no representations about the suitability of this software
  11.   for any purpose.  It is provided "as is" without express or implied warranty.
  12.  
  13.     July, 1989
  14.      Andrew C. Payne
  15. */
  16.  
  17. /* ----- Includes ----- */
  18.  
  19. #include <stdio.h>
  20. #include <alloc.h>
  21. #include <conio.h>
  22. #include <dos.h>
  23. #include "pmp.h"
  24. #include "ports.h"
  25.  
  26. #define    MAXRXQUEUE    20        /* max items in queue */
  27. #define    MAXL1DSIZE    400        /* max size of level 1 data field */
  28.  
  29. extern word timer(void);
  30. extern word waittrans(word from);
  31.  
  32. /* ---- Local Variables ----- */
  33.  
  34. static struct ax25_level1 *RXQueue[MAXRXQUEUE];    /* Receive queue */
  35. static int    RXQSize;            /* number of items in queue */
  36.  
  37. /* ----- Subroutines ----- */
  38.  
  39. /* RXCarrier()
  40.     Returns TRUE if receive carrier detected.
  41. */
  42. int RXCarrier()
  43. {
  44.     register byte    x;
  45.  
  46.     x = inportb(CDPort) & CDBit;
  47.     return CDLevel ? x : !x;
  48. }
  49.  
  50. /* RXLevel1()
  51.     Called whenever a RX carrier is detected, handles packet reception.
  52.     Received packets are put in the receive queue.
  53.  
  54.     Returns the number of packets in the RXQueue.
  55. */
  56. int RXLevel1(void)
  57. {
  58.     int    j;
  59.     word    t1,t2;            /* transition times */
  60.     int    gotsync;        /* TRUE if we have gotten a flag */
  61.     int    bits;            /* bit time */
  62.     byte    *p;            /* pointer to RX buffer */
  63.     byte    c;            /* current rec'd character */
  64.     int    b;            /* bits in c */
  65.     struct ax25_level1    *RXB;    /* current RX buffer */
  66.     int    bitcount;        /* count of bits received */
  67.  
  68.     t1 = timer();            /* current time */
  69.     gotsync = FALSE;        /* we have no flag */
  70.     ShowTXRX(FALSE,TRUE);        /* update screen status */
  71.     bitcount = 0;            /* start counting bits */
  72.     disable();            /* no interruptions */
  73.  
  74. restart:
  75.     if(RXQSize >= MAXRXQUEUE) {    /* is the RX Queue full? */
  76.         RXQOverflow++;        /* count overflows */
  77.         enable();        /* re-enable interrupts */
  78.         return RXQSize;        /* abort */
  79.     }
  80.  
  81.     RXB = RXQueue[RXQSize];        /* next queue entry */
  82.     p = RXB->data;            /* initialize */
  83.     b = c = 0;
  84.  
  85.     while(RXCarrier()) {
  86.  
  87. /* wait for next transition */
  88.         t2 = waittrans(t1-20000);
  89.         bits = (((t1 - t2) + 994) / BITTIME) - 1;
  90.         bitcount += (bits + 1);
  91.         t1 = t2;
  92.  
  93. /* check for SYNC character */
  94.         if(bits == 6) {
  95.  
  96. /* if we've already got a sync, check for an incoming packet */
  97.             if(gotsync) {
  98.                 if(p != RXB->data) {
  99.                     if(b == 1) {    /* got one! */
  100.                         RXB->len = p - RXB->data;
  101.                         RXQSize++;        /* add item */
  102.                         goto restart;        /* do again */
  103.                     } else
  104.                         RXFrameErr++;
  105.                 }
  106.             }
  107.             gotsync = TRUE;
  108.             b = c = 0;
  109.  
  110. /* store bits in the incoming packet */
  111.         } else if(bits >= 0 && bits < 6) {
  112.             j = bits;        /* store the bits in C */
  113.             while(j--) {
  114.                 c >>= 1;
  115.                 b++;
  116.                 c |= 0x80;
  117.                 if(b == 8) {
  118.                     *p++ = c;    /* store it */
  119.                     c = 0;
  120.                     b = 0;
  121.                 }
  122.             }
  123.             if(bits != 5) {
  124.                 c >>= 1;
  125.                 b++;
  126.                 if(b == 8) {
  127.                     *p++ = c;    /* store it */
  128.                     c = 0;
  129.                     b = 0;
  130.                 }
  131.             }
  132.         } else            /* some strange bit count */
  133.             gotsync = FALSE;
  134.  
  135. /* check for RX buffer overflow */
  136.         if((p - RXB->data) > MAXL1DSIZE) {    /* packet too long */
  137.             RXBOverflow++;
  138.             gotsync = FALSE;
  139.             goto restart;
  140.         }
  141.     }
  142.  
  143. /* lost carrier */
  144.     enable();                /* interrupts allowed */
  145.     ShowTXRX(FALSE,FALSE);
  146.     ClockAdjust(bitcount);            /* speed up clock */
  147.     return RXQSize;
  148. }
  149.  
  150. /* RXProcess()
  151.     Processes the packets sitting in the level1 RX queue.  Valid
  152.     packets are handed up to the AX.25 routines.
  153. */
  154. void RXProcess(void)
  155. {
  156.     int    i;
  157.  
  158. /* empty RX queue? */
  159.     if(RXQSize == 0)
  160.         return;
  161.  
  162. /* process RXQueue items */
  163.     for(i=0; i<RXQSize; i++) {
  164.  
  165. /* if CRC is good, show & handle packet */
  166.         if(CRCCheck(RXQueue[i])) {
  167.             RXCount++;
  168.             AX25Level2(RXQueue[i]);        /* upcall */
  169.         } else {
  170.             RXCRCErr++;
  171.             if(PassMode) {
  172.                 uprintf(BrightAttr,"~");
  173.                 AX25Level2(RXQueue[i]);    /* upcall */
  174.             }
  175.         }
  176.     }
  177.  
  178. /* empty RX Queue */
  179.     RXQSize = 0;
  180. }
  181.  
  182. /* RXInit()
  183.     Initialize the RX routines:  allocate the level 1 receive buffers.
  184. */
  185. void RXInit()
  186. {
  187.     int    i;
  188.  
  189. /* allocate the RX Queue */
  190.     for(i=0; i<MAXRXQUEUE; i++) {
  191.         if((RXQueue[i] = malloc(sizeof(struct ax25_level1) + MAXL1DSIZE))
  192.             == NULL)
  193.                 OutOfMemory();
  194.     }
  195.  
  196.  
  197.     RXQSize = 0;        /* empty queue */
  198. }